package com.ttsx.service.impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.ttsx.core.common.constant.CacheConstants;
import com.ttsx.core.common.exception.TTSXException;
import com.ttsx.core.common.result.ResultCodeEnum;
import com.ttsx.core.common.util.JwtUtils;
import com.ttsx.pojo.dto.auth.AccountLoginDTO;
import com.ttsx.pojo.entity.User;
import com.ttsx.service.AdminService;
import com.ttsx.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author wb
 * @since 2025-03-02
 */

@Service
public class AdminServiceImpl implements AdminService {
    @Autowired
    private UserService userService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public String genCaptcha(String randomStr) {
        // 定义图形验证码的长和宽
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(100, 40, 5, 100);

        // 验证码值
        String code = lineCaptcha.getCode();

        // 将验证码缓存到 redis 中，1 分钟后失效
        redisTemplate.opsForValue().set(CacheConstants.CAPTCHA_KEY + randomStr, code, 1, TimeUnit.MINUTES);

        // 验证码以base64的格式返回到客户端
        return lineCaptcha.getImageBase64Data();
    }

    @Override
    public Map<String, String> login(AccountLoginDTO accountLoginDTO) {
        // 验证验证码
        validateCode(accountLoginDTO.getCaptchaKey(), accountLoginDTO.getCaptcha());

        User user = userService.getByUsername(accountLoginDTO.getUsername());

        if (user == null) {
            throw new TTSXException(ResultCodeEnum.USERNAME_PASSWORD_ERROR);
        }

        if(!"ADMIN".equalsIgnoreCase(user.getRole())){
            throw new TTSXException(ResultCodeEnum.PERMISSION_DENIED);
        }

        if (!DigestUtil.md5Hex(accountLoginDTO.getPassword()).equals(user.getPassword())) {
            throw new TTSXException(ResultCodeEnum.USERNAME_PASSWORD_ERROR);
        }

        // 生成 token
        Map<String, String> claimMap = new HashMap<>();
        claimMap.put("id", user.getId().toString());
        claimMap.put("username", user.getUsername());
        String token = JwtUtils.createToken(claimMap);

        // 将用户信息保存到 redis 中
        redisTemplate.opsForValue().set(CacheConstants.USER_KEY + token, user, 7, TimeUnit.DAYS);

        // 封装结果
        Map<String, String> result = new HashMap<>();
        result.put("token", token);

        return result;
    }

    @Override
    public User info(String token) {
        return (User) redisTemplate.opsForValue().get(CacheConstants.USER_KEY + token.substring(7));
    }

    @Override
    public Boolean logout(String token) {
        return redisTemplate.delete(CacheConstants.USER_KEY + token.substring(7));
    }


    private void validateCode(String cacheKey, String code) {
        // 获取缓存中的验证码
        String cacheCode = (String) redisTemplate.opsForValue().get(CacheConstants.CAPTCHA_KEY + cacheKey);

        // 判断验证码是否存在
        if (ObjectUtil.isEmpty(cacheCode)) {
            throw new TTSXException(ResultCodeEnum.CAPTCHA_NOT_EXISTS);
        }

        // 验证验证码
        if (!code.equalsIgnoreCase(cacheCode)) {
            throw new TTSXException(ResultCodeEnum.CAPTCHA_ERROR);
        }

        // 删除验证码
        redisTemplate.delete(CacheConstants.CAPTCHA_KEY + cacheKey);
    }

}
